<template>
  <tm-sheet
    :eventPenetrationEnabled="true"
    :transparent="true"
    :margin="props.margin"
    :padding="props.padding"
  >
    <tm-sheet
      :transparent="propsDetail.disabled ? true : props.transparent"
      :round="props.round"
      no-level
      :margin="[0, 0]"
      :padding="_inputPadding"
      :border="props.border"
      :text="props.text"
      :color="_color"
      :outlined="props.outlined"
      :shadow="props.shadow"
      :linear="props.linear"
      :linearDeep="props.linearDeep"
      _style="transition:border 0.24s"
      :style="[propsDetail.disabled ? { backgroundColor: '#9e9e9e63', borderRadius: '8rpx' } : {}]"
    >
      <view
        class="flex flex-row relative"
        @click="inputClick($event, '')"
        :class="[
          propsDetail.type == 'textarea' ? propsDetail.layoutAlign : 'flex-row-center-start',
        ]"
        :style="[
          propsDetail.autoHeight && propsDetail.type == 'textarea'
            ? {}
            : { height: `${_height}rpx` },
        ]"
      >
        <view v-if="propsDetail.search || propsDetail.searchLabel" class="px-9"></view>
        <slot name="left"></slot>
        <view v-if="propsDetail.prefix" class="pr-16">
          <tm-icon
            _style="transition:color 0.24s"
            :font-size="propsDetail.fontSize"
            :color="props.prefixColor"
            :name="propsDetail.prefix"
          ></tm-icon>
        </view>
        <view v-if="propsDetail.prefixLabel" class="pr-24">
          <tm-text
            _style="transition:color 0.24s"
            :font-size="propsDetail.fontSize"
            :color="props.prefixColor"
            :label="propsDetail.prefixLabel"
          ></tm-text>
        </view>

        <view
          v-if="!isAndroid"
          @click="inputClick($event, 'ali')"
          class="flex-1 relative flex-row flex"
          :style="[{ width: '0px' }]"
        >
          <!-- <view @click.stop="emits('click',$event)" class=" l-0 t-0 flex-1 " :style="{height: `${_height}rpx`,background:'red'}"></view> -->
          <input
            class="flex-1"
            :userInteractionEnabled="false"
            v-if="propsDetail.type != 'textarea'"
            v-model="_value"
            :focus="propsDetail.focus"
            @focus="focus"
            @blur="blur"
            @confirm="confirm"
            @input="inputHandler"
            @keyboardheightchange="emits('keyboardheightchange', $event)"
            :password="showPasswordText"
            :disabled="propsDetail.disabled"
            :cursorSpacing="propsDetail.cursorSpacing"
            :confirmType="propsDetail.confirmType"
            :confirmHold="propsDetail.confirmHold"
            :autoBlur="propsDetail.autoBlur"
            :holdKeyboard="propsDetail.holdKeyboard"
            :adjustPosition="propsDetail.adjustPosition"
            :readonly="propsDetail.readyOnly"
            :type="propsDetail.type"
            :maxlength="maxlength"
            :placeholder="propsDetail.placeholder"
            :style="[
              {
                height: `${_height}rpx`,
                color: propsDetail.fontColor ? propsDetail.fontColor : tmcomputed.textColor,
                'text-align': props.align,
                fontSize: `${propsDetail.fontSize_px}px`,
                transition: 'color 0.24s',
              },
            ]"
            :placeholder-style="`fontSize:${propsDetail.fontSize_px}px;${props.placeholderStyle}`"
            :ready-only="propsDetail.readyOnly"
          />

          <textarea
            :userInteractionEnabled="false"
            v-if="propsDetail.type == 'textarea'"
            style="resize: none"
            v-model="_value"
            :focus="propsDetail.focus"
            @focus="focus"
            @blur="blur"
            @confirm="confirm"
            @input="inputHandler"
            @keyboardheightchange="emits('keyboardheightchange', $event)"
            :disabled="propsDetail.disabled"
            :placeholder="propsDetail.placeholder"
            :cursorSpacing="propsDetail.cursorSpacing"
            :confirmHold="propsDetail.confirmHold"
            :autoBlur="propsDetail.autoBlur"
            :holdKeyboard="propsDetail.holdKeyboard"
            :cursor="propsDetail.cursor"
            :show-confirm-bar="propsDetail.showConfirmBar"
            :selectionStart="propsDetail.selectionStart"
            :selectionEnd="propsDetail.selectionEnd"
            :disable-default-padding="propsDetail.disableDefaultPadding"
            :fixed="propsDetail.fixed"
            :autoHeight="propsDetail.autoHeight"
            :readonly="propsDetail.readyOnly"
            :adjustPosition="propsDetail.adjustPosition"
            :type="propsDetail.type"
            :maxlength="maxlength"
            :style="[
              propsDetail.autoHeight ? {} : { height: `${_height}rpx` },
              {
                width: 'auto',
                'word-break': 'break-word',
                color: propsDetail.fontColor ? propsDetail.fontColor : tmcomputed.textColor,
                'text-align': props.align,
                fontSize: `${propsDetail.fontSize_px}px`,
                transition: 'color 0.24s',
              },
            ]"
            class="wrap flex-1"
            :placeholder-style="`fontSize:${propsDetail.fontSize_px}px;${props.placeholderStyle}`"
            :ready-only="propsDetail.readyOnly"
          ></textarea>
        </view>
        <view v-if="isAndroid" class="flex-1 relative flex-row flex" :style="[{ width: '0px' }]">
          <!-- <view @click.stop="emits('click',$event)" class=" l-0 t-0 flex-1 " :style="{height: `${_height}rpx`,background:'red'}"></view> -->
          <input
            class="flex-1"
            @click.stop="emits('click', $event)"
            :userInteractionEnabled="false"
            v-if="propsDetail.type != 'textarea'"
            v-model="_value"
            :focus="propsDetail.focus"
            @focus="focus"
            @blur="blur"
            @confirm="confirm"
            @input="inputHandler"
            @keyboardheightchange="emits('keyboardheightchange', $event)"
            :password="showPasswordText"
            :disabled="propsDetail.disabled"
            :cursorSpacing="propsDetail.cursorSpacing"
            :confirmType="propsDetail.confirmType"
            :confirmHold="propsDetail.confirmHold"
            :autoBlur="propsDetail.autoBlur"
            :holdKeyboard="propsDetail.holdKeyboard"
            :adjustPosition="propsDetail.adjustPosition"
            :type="propsDetail.type"
            :readonly="propsDetail.readyOnly"
            :maxlength="maxlength"
            :placeholder="propsDetail.placeholder"
            :style="[
              {
                height: `${_height}rpx`,
                color: propsDetail.fontColor ? propsDetail.fontColor : tmcomputed.textColor,
                'text-align': props.align,
                fontSize: `${propsDetail.fontSize_px}px`,
              },
            ]"
            :placeholder-style="`fontSize:${propsDetail.fontSize_px}px;${props.placeholderStyle}`"
          />
          <textarea
            @click.stop="emits('click', $event)"
            :userInteractionEnabled="false"
            v-if="propsDetail.type == 'textarea'"
            style="resize: none"
            v-model="_value"
            :focus="propsDetail.focus"
            @focus="focus"
            @blur="blur"
            @confirm="confirm"
            @input="inputHandler"
            @keyboardheightchange="emits('keyboardheightchange', $event)"
            :disabled="propsDetail.disabled"
            :placeholder="propsDetail.placeholder"
            :cursorSpacing="propsDetail.cursorSpacing"
            :confirmHold="propsDetail.confirmHold"
            :autoBlur="propsDetail.autoBlur"
            :holdKeyboard="propsDetail.holdKeyboard"
            :adjustPosition="propsDetail.adjustPosition"
            :autoHeight="propsDetail.autoHeight"
            :cursor="propsDetail.cursor"
            :show-confirm-bar="propsDetail.showConfirmBar"
            :selectionStart="propsDetail.selectionStart"
            :selectionEnd="propsDetail.selectionEnd"
            :disable-default-padding="propsDetail.disableDefaultPadding"
            :readonly="propsDetail.readyOnly"
            :fixed="propsDetail.fixed"
            :type="propsDetail.type"
            :maxlength="maxlength"
            :style="[
              propsDetail.autoHeight ? {} : { height: `${_height}rpx` },
              {
                width: 'auto',
                'word-break': 'break-word',
                color: propsDetail.fontColor ? propsDetail.fontColor : tmcomputed.textColor,
                'text-align': props.align,
                fontSize: `${propsDetail.fontSize_px}px`,
              },
            ]"
            class="wrap flex-1"
            :placeholder-style="`fontSize:${propsDetail.fontSize_px}px;${props.placeholderStyle}`"
          ></textarea>
        </view>
        <view @click="clearBtn" class="pl-16" v-if="propsDetail.showClear && _valueLenChar > 0">
          <tm-icon
            _style="transition:color 0.24s"
            :userInteractionEnabled="false"
            :font-size="propsDetail.fontSize"
            name="tmicon-times-circle-fill"
          ></tm-icon>
        </view>
        <view class="pl-16" v-if="_requiredError">
          <tm-icon
            _style="transition:color 0.24s"
            :font-size="propsDetail.fontSize"
            name="tmicon-exclamation-circle"
          ></tm-icon>
        </view>
        <view class="pl-16" v-if="propsDetail.suffix">
          <tm-icon
            _style="transition:color 0.24s"
            :font-size="propsDetail.fontSize"
            :color="props.suffixColor"
            :name="propsDetail.suffix"
          ></tm-icon>
        </view>

        <view v-if="propsDetail.suffixLabel" class="pl-16">
          <tm-text
            _style="transition:color 0.24s"
            :font-size="propsDetail.fontSize"
            :color="props.suffixColor"
            :label="propsDetail.suffixLabel"
          ></tm-text>
        </view>

        <view @click="changeSeePassword" class="pl-16" v-if="showPasswordIcon">
          <!-- tmicon-eyeslash-fill -->
          <tm-icon
            _style="transition:color 0.24s"
            :userInteractionEnabled="false"
            :font-size="propsDetail.fontSize"
            :name="showPasswordText ? 'tmicon-eyeslash-fill' : 'tmicon-eye-fill'"
          ></tm-icon>
        </view>

        <!-- #ifndef MP-ALIPAY -->
        <view
          v-if="propsDetail.showCharNumber && _valueLenChar > 0 && propsDetail.type != 'textarea'"
          class="pl-16 flex-row flex"
        >
          <tm-text _style="transition:color 0.24s" :label="_valueLenChar"></tm-text>
          <tm-text
            _style="transition:color 0.24s"
            v-if="propsDetail.maxlength > 0"
            :label="'/' + propsDetail.maxlength"
          ></tm-text>
        </view>
        <!-- 原因是支付宝小程序自带了计数器。会导致重叠。 -->
        <view
          v-if="propsDetail.showCharNumber && _valueLenChar > 0 && propsDetail.type == 'textarea'"
          class="pl-16 flex-row flex absolute r-0"
          :class="[`b-${12}`]"
        >
          <tm-text _style="transition:color 0.24s" :label="_valueLenChar"></tm-text>
          <tm-text
            _style="transition:color 0.24s"
            v-if="propsDetail.maxlength > 0"
            :label="'/' + propsDetail.maxlength"
          ></tm-text>
        </view>
        <!-- #endif -->
        <slot name="right">
          <view v-if="propsDetail.search || propsDetail.searchLabel" class="pl-16">
            <TmButton
              :width="props.searchWidth"
              :followTheme="props.followTheme"
              @click="searchClick"
              :color="props.focusColor"
              :font-size="24"
              :height="_height - 11"
              :padding="[16, 0]"
              :block="!props.searchWidth"
              :margin="[0, 0]"
              :fontColor="props.searchFontColor"
              :icon="propsDetail.search"
              :label="propsDetail.searchLabel"
            ></TmButton>
          </view>
        </slot>
      </view>
    </tm-sheet>
  </tm-sheet>
</template>

<script lang="ts" setup>
  import { computed, PropType, ref, watch, getCurrentInstance, inject, toRaw } from 'vue';
  import { inputPushItem, rulesItem } from './../tm-form-item/interface';
  import tmSheet from '../tm-sheet/tm-sheet.vue';
  import tmIcon from '../tm-icon/tm-icon.vue';
  import tmText from '../tm-text/tm-text.vue';
  import {
    custom_props,
    computedTheme,
    computedClass,
    computedStyle,
    computedDark,
  } from '../../tool/lib/minxs';
  import { useTmpiniaStore } from '../../tool/lib/tmpinia';
  import TmButton from '../tm-button/tm-button.vue';
  import { useDebounceFn } from '@vueuse/core';
  const store = useTmpiniaStore();
  const emits = defineEmits([
    'focus',
    'blur',
    'confirm',
    'input',
    'update:modelValue',
    'clear',
    'search',
    'keyboardheightchange',
    'click',
  ]);
  const proxy = getCurrentInstance()?.proxy ?? null;
  const props = defineProps({
    ...custom_props,
    followTheme: {
      type: [Boolean, String],
      default: false,
    },
    color: {
      type: String,
      default: 'grey-4',
    },
    searchFontColor: {
      type: String,
      default: '',
    },
    searchWidth: {
      type: Number,
      default: 0,
    },
    prefixColor: {
      type: String,
      default: '',
    },
    suffixColor: {
      type: String,
      default: '',
    },
    //激活时的主题配色。
    focusColor: {
      type: String,
      default: 'grey-4',
    },
    //默认使用自动配色
    fontColor: {
      type: String,
      default: '',
    },
    text: {
      type: Boolean,
      default: true,
    },
    outlined: {
      type: Boolean,
      default: false,
    },
    border: {
      type: Number,
      default: 0,
    },
    transparent: {
      type: Boolean,
      default: false,
    },
    round: {
      type: Number,
      default: 3,
    },
    shadow: {
      type: Number,
      default: 0,
    },
    margin: {
      type: Array as PropType<Array<number>>,
      default: () => [0, 0],
    },
    padding: {
      type: Array as PropType<Array<number>>,
      default: () => [0, 0],
    },
    height: {
      type: Number,
      default: 64,
    },
    //前缀图标
    prefix: {
      type: String,
      default: '',
    },
    //前缀文字
    prefixLabel: {
      type: String,
      default: '',
    },
    //后缀图标
    suffix: {
      type: String,
      default: '',
    },
    //后缀文字
    suffixLabel: {
      type: String,
      default: '',
    },

    fontSize: {
      type: Number,
      default: 30,
    },
    //tmicon-search
    search: {
      type: String,
      default: '',
    },
    //搜索
    searchLabel: {
      type: String,
      default: '',
    },
    showClear: {
      type: Boolean,
      default: false,
    },
    password: {
      type: Boolean,
      default: false,
    },
    //是否禁用
    disabled: {
      type: Boolean,
      default: false,
    },
    placeholder: {
      type: String,
      default: '请输入内容',
    },
    //错误时，提示的文本。
    errorLabel: {
      type: String,
      default: '请输入内容',
    },
    //对齐方式。
    //left,right,center
    align: {
      type: String as PropType<'left' | 'right' | 'center'>,
      default: 'left',
    },
    modelValue: {
      type: [String, Number],
      default: '',
    },
    inputPadding: {
      type: Array as PropType<Array<number>>,
      default: () => [24, 0],
    },
    //是否显示字符统计。
    showCharNumber: {
      type: Boolean,
      default: false,
    },
    maxlength: {
      type: Number,
      default: -1,
    },
    type: {
      type: String as PropType<
        'text' | 'number' | 'idcard' | 'digit' | 'tel' | 'safe-password' | 'nickname' | 'textarea'
      >,
      default: 'text',
    },
    cursorSpacing: {
      type: Number,
      default: 24,
    },
    confirmType: {
      type: String as PropType<'send' | 'search' | 'next' | 'go' | 'done'>,
      default: 'done',
    },
    confirmHold: {
      type: Boolean,
      default: false,
    },
    autoBlur: {
      type: Boolean,
      default: true,
    },
    holdKeyboard: {
      type: Boolean,
      default: false,
    },
    adjustPosition: {
      type: Boolean,
      default: true,
    },
    //默认的聚集状态
    focus: {
      type: Boolean,
      default: false,
    },
    cursor: {
      type: Number,
      default: 0,
    },
    showConfirmBar: {
      type: Boolean,
      default: true,
    },
    selectionStart: {
      type: Number,
      default: -1,
    },
    selectionEnd: {
      type: Number,
      default: -1,
    },
    disableDefaultPadding: {
      type: Boolean,
      default: false,
    },
    fixed: {
      type: Boolean,
      default: false,
    },
    placeholderStyle: {
      type: String,
      default: 'color: #969799',
    },
    autoHeight: {
      type: Boolean,
      default: false,
    },
    readyOnly: {
      type: Boolean,
      default: false,
    },
    /**横向布局的对齐类,主要是用来配置文本域时,左图标需要顶对齐或者左中对齐. */
    layoutAlign: {
      type: String,
      default: 'flex-row-top-start',
    },
  });

  let parentFormItem: any = proxy?.$parent;
  while (parentFormItem) {
    if (parentFormItem?.tmFormComnameFormItem == 'tmFormComnameFormItem' || !parentFormItem) {
      break;
    } else {
      parentFormItem = parentFormItem?.$parent ?? undefined;
    }
  }

  const isAndroid = ref(false);
  isAndroid.value = uni.getSystemInfoSync().osName == 'android' ? true : false;
  const _height = computed(() => props.height);
  const _inputPadding = computed(() => {
    if (props.search !== '' || props.searchLabel !== '') {
      return [4, 0];
    }
    return props.inputPadding;
  });
  let timerId: any = NaN;
  function debounce(func: Function, wait = 500, immediate = false) {
    // 清除定时器
    if (!isNaN(timerId)) clearTimeout(timerId);
    // 立即执行，此类情况一般用不到
    if (immediate) {
      var callNow = !timerId;
      timerId = setTimeout(() => {
        timerId = NaN;
      }, wait);

      if (callNow) typeof func === 'function' && func();
    } else {
      // 设置定时器，当最后一次操作后，timeout不会再被清除，所以在延时wait毫秒后执行func回调方法
      timerId = setTimeout(() => {
        typeof func === 'function' && func();
        timerId = NaN;
      }, wait);
    }
  }
  const propsDetail = computed(() => {
    return {
      ...props,
      fontSize_px: uni.upx2px(props.fontSize),
    };
  });
  const _blackValue = props.modelValue;
  // 设置响应式全局组件库配置表。
  const tmcfg = computed(() => store.tmStore);
  //自定义样式：
  const customCSSStyle = computed(() => computedStyle(props));
  //自定类
  const customClass = computed(() => computedClass(props));
  //是否暗黑模式。
  const isDark = computed(() => computedDark(props, tmcfg.value));
  //当前是否显示检验错误状态？
  const _requiredError = ref(false);
  //是否聚焦中。
  const _foucsActive = ref(props.focus || false);
  watch(
    () => props.focus,
    () => {
      _foucsActive.value = props.focus;
    },
  );
  const _color = computed(() => {
    let color = props.color;
    if (_foucsActive.value) {
      if (props.followTheme && store.tmStore.color) {
        color = store.tmStore.color;
      } else {
        color = props.focusColor;
      }
    }
    if (_requiredError.value) color = 'red';
    return color;
  });
  //计算主题
  const tmcomputed = computed(() => {
    const _props = { ...props, color: _color.value };
    return computedTheme(_props, isDark.value, tmcfg.value);
  });

  //显示密码和关闭密码。
  const showPasswordText = ref(propsDetail.value.password);
  const showPasswordIcon = computed(() => props.password);
  const _errorLabel = ref(props.errorLabel);
  const _value = ref(props.modelValue);
  // const _valueLenChar = computed(() => {
  //   //在ios上字符的长度不能采用str.length来计算。因为一个中文=2。一个英文=1；
  //   let str = String(_value.value).split('');
  //   return str.length;
  // });
  const _valueLenChar = ref(0);
  watch(
    () => props.modelValue,
    (val) => {
      if (val !== _value.value) _value.value = val;
      let str = String(val).split('');
      _valueLenChar.value = str.length;
    },
  );
  // watch(
  //   () => props.modelValue,
  //   () => (_value.value = props.modelValue),
  // );

  function searchClick() {
    emits('search', _value.value);
  }
  function clearBtn() {
    _value.value = '';
    emits('update:modelValue', '');
    emits('clear');
  }
  function changeSeePassword() {
    showPasswordText.value = !showPasswordText.value;
  }
  function focus(e: any) {
    _foucsActive.value = true;
    emits('focus', e);
    // pushFormItem();
  }
  function blur(e: any) {
    _foucsActive.value = false;
    // pushFormItem();
    emits('blur', e);
  }
  function confirm() {
    emits('confirm', _value.value);
  }

  const inputHandler = useDebounceFn((e: CustomEvent) => {
    // console.log(e.detail.value);

    // #ifndef MP-WEIXIN
    // _value.value = e.detail.value;
    // #endif
    emits('input', e.detail.value);
    emits('update:modelValue', e.detail.value);
  });

  // function inputHandler(e: CustomEvent) {
  //   // #ifndef MP-WEIXIN
  //   _value.value = e.detail.value;
  //   // #endif
  //   emits('input', e.detail.value);
  //   emits('update:modelValue', e.detail.value);

  //   return e.detail.value;
  // }
  function inputClick(e: Event, type: string) {
    // e.stopPropagation();

    if (type == 'ali') {
      debounce(
        () => {
          emits('click', e);
        },
        200,
        true,
      );
      return;
    } else {
      debounce(() => emits('click', e), 200, true);
    }
  }
</script>

<style scoped>
  /* #ifndef APP-NVUE */
  input,
  textarea {
    background-color: transparent;
    background: transparent;
  }

  /* #endif */
</style>
